﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Google.Translates.Core;
using ml_test_google_trans_app.Google.Translates.WebService;


namespace ml_test_google_trans_app
{
    public partial class TransTextByWebService : Form
    {
        protected const string FUNC_NAME_TRANS = "Translates", FUNC_NAME_DETECT = "Detect";
        private const string m_BaseTestResultDir = "MultiTransResultByWebServiceRef\\Translates";
        private const string m_ResultDirPath_WordsAmount = "WordsAmountTestResultByWebServiceRef\\Translates\\DiffWords";
        private const string m_ResultDirPath_MultiTrans_SameWords = m_BaseTestResultDir + "\\SameWords";
        private const string m_ResultDirPath_MultiTrans_DiffWords = m_BaseTestResultDir + "\\DiffWords";
        private readonly List<Thread> m_Threads = new List<Thread>();


        protected DateTime m_MultiTransEndDate = DateTime.MinValue;
        protected DateTime m_MultiTransStartDate = DateTime.MaxValue;
        protected string m_ResultDirPath = "";

        public TransTextByWebService()
        {
            InitializeComponent();
        }


        protected void StartMultiThreads(int amount, string testFuncName)
        {
            for (int i = 0; i < amount; i++)
            {
                var thrd = new Thread(TestMultiTrans);
                thrd.Start(new StringCollection
                               {
                                   i.ToString(),
                                   txtSrcSentence.Text,
                                   testFuncName,
                                   lstTargeLanguage.SelectedItem.ToString()
                               });
                m_Threads.Add(thrd);
            }
        }

        protected void StartMultiThreads(StringCollection scSentences, string testFuncName)
        {
            for (int i = 0; i < scSentences.Count; i++)
            {
                var thrd = new Thread(TestMultiTrans);
                thrd.Start(new StringCollection
                               {
                                   i.ToString(),
                                   scSentences[i],
                                   testFuncName,
                                   lstTargeLanguage.SelectedItem.ToString()
                               });
                m_Threads.Add(thrd);
            }
        }

        protected void CloseThreads()
        {
            while (m_Threads.Count > 0)
            {
                m_Threads[0].Abort();
                m_Threads.RemoveAt(0);
            }
        }

        private void OutputTextLog(string filePath, string strContext, DateTime startDate, DateTime endDate)
        {
            if (File.Exists(filePath)) File.Delete(filePath);
            var sw = new StreamWriter(filePath, false, Encoding.UTF8);
            try
            {
                sw.WriteLine(strContext);
                sw.WriteLine("Start Date:[" + startDate.ToString("yyyyMMdd HH:mm:ss.fff") + "]");
                sw.WriteLine("End   Date:[" + endDate.ToString("yyyyMMdd HH:mm:ss.fff") + "]");
                sw.WriteLine("Used  Time:[" + (endDate - startDate).TotalMilliseconds + "]ms");
            }
            finally
            {
                sw.Dispose();
                sw.Close();
            }
        }

        private void TestMultiTrans(object info)
        {
            m_MultiTransEndDate = DateTime.MinValue;
            m_MultiTransStartDate = DateTime.MaxValue;
            if (info == null || !(info is StringCollection)) return;
            var sc = (StringCollection) info;
            if (sc.Count != 4) return;
            string srcSentence = sc[1];
            string testFuncName = sc[2];
            string trgLangKey = sc[3];
            DateTime startDate = DateTime.Now;
            if (startDate < m_MultiTransStartDate) m_MultiTransStartDate = startDate;
            var sbContext = new StringBuilder();
            if (testFuncName == FUNC_NAME_TRANS)
            {
                string srcAutoCheckLangKey = null;
                string strTrgWords = "";
                //

                var reVal = new DoTranslates().TranslateTheLongSentence(srcSentence, trgLangKey);
                if (string.IsNullOrEmpty(reVal.ErrorMessage))
                {
                    srcAutoCheckLangKey = reVal.SourceLanguageKey;
                    strTrgWords = reVal.TargetText;
                }

                //
                sbContext.Append("Source Words[ " + srcSentence + " ]\r\n\r\n");
                if (!string.IsNullOrEmpty(srcAutoCheckLangKey))
                    sbContext.Append("Source LangKey[ " + srcAutoCheckLangKey + " ]\r\n\r\n");
                sbContext.Append("Target Words[" + strTrgWords + "]\r\n\r\n");
                sbContext.Append("Target LangKey[" + trgLangKey + "]\r\n\r\n");
            }

            DateTime endDate = DateTime.Now;
            if (endDate > m_MultiTransEndDate) m_MultiTransEndDate = endDate;
            string fileName = Convert.ToInt32(sc[0]).ToString().PadLeft(5, '0');
            OutputTextLog(
                m_ResultDirPath + "\\" + fileName + "_UsedTime[" +
                Math.Round((endDate - startDate).TotalMilliseconds, 0) + "]ms.txt", sbContext.ToString(), startDate,
                endDate);
        }

        private void MultiTrans_Click(object sender, EventArgs e)
        {
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            
        }

        private string GetTextFileContext(string filePath)
        {
            string reString = "";

            if (File.Exists(filePath))
            {
                var sr = new StreamReader(filePath, Encoding.UTF8);
                try
                {
                    reString = sr.ReadToEnd();
                }
                finally
                {
                    sr.Dispose();
                    sr.Close();
                }
            }

            return reString;
        }

        private string GetSentence(string strContext, string[] words, int startWordIndex, int wordsAmount)
        {
            string reStr = "";
            if (words.Length - 1 > (startWordIndex + wordsAmount))
            {
                int startIndex = 0;
                for (int i = 0; i < startWordIndex; i++)
                    startIndex += words[i].Length;
                int len = 0;
                for (int i = startIndex; i < startIndex + wordsAmount; i++)
                {
                    if (i < words.Length)
                        len += (words[i].Length + 1);
                }
                reStr = strContext.Substring(startIndex, len);
            }
            else
                throw new ArgumentException("参数有问题");
            return reStr;
        }


        private void btnWordsAmountByFile_Click(object sender, EventArgs e)
        {
            m_MultiTransStartDate = DateTime.Now;
            string sourceFileDir = AppDomain.CurrentDomain.BaseDirectory + "Diff_Words\\ForWordsAmountTest";
            if (!Directory.Exists(sourceFileDir)) return;
            string[] fsNames = Directory.GetFiles(sourceFileDir, "*.txt");
            string dirPath = m_ResultDirPath_WordsAmount;
            if (Directory.Exists(dirPath)) Directory.Delete(dirPath, true);
            Directory.CreateDirectory(dirPath);
            foreach (string fName in fsNames)
            {
                string fileShotName = fName.Substring(fName.LastIndexOf("\\") + 1);
                string fileKey = fileShotName.Remove(fileShotName.Length - 4);
                m_ResultDirPath = dirPath + "\\WordsAmount_" + fileKey;
                Directory.CreateDirectory(m_ResultDirPath);
                var sbContext = new StringBuilder();
                string srcWords = GetTextFileContext(fName);
                string trgLangKey = lstTargeLanguage.SelectedItem.ToString();
                string trgWords = "";
                string srcAutoCheckLangKey = "";
                DateTime startDate = DateTime.Now;
                //=======================================
                var reVal = new DoTranslates().TranslateTheLongSentence(srcWords, trgLangKey);
                if(string.IsNullOrEmpty(reVal.ErrorMessage))
                {
                    srcAutoCheckLangKey = reVal.SourceLanguageKey;
                    trgWords = reVal.TargetText;
                }

                sbContext.Append("Source Words[ " + srcWords + " ]\r\n\r\n");
                if (!string.IsNullOrEmpty(srcAutoCheckLangKey))
                    sbContext.Append("Source LangKey[ " + srcAutoCheckLangKey + " ]\r\n\r\n");
                sbContext.Append("Target Words[" + trgWords + "]\r\n\r\n");
                sbContext.Append("Target LangKey[" + trgLangKey + "]\r\n\r\n");
                DateTime endDate = DateTime.Now;
                if (endDate > m_MultiTransEndDate) m_MultiTransEndDate = endDate;
                OutputTextLog(
                    m_ResultDirPath + "\\" + fileKey + "_UsedTime[" +
                    Math.Round((endDate - startDate).TotalMilliseconds, 0) + "]ms.txt",
                    sbContext.ToString(), startDate, endDate);
                //Thread.Sleep(5000);
            }
            m_MultiTransEndDate = DateTime.Now;
            string strMsg = "Total Used Time_[" +
                            (m_MultiTransEndDate - m_MultiTransStartDate).TotalMilliseconds + "]ms";
            string msgFilePath = dirPath + "\\" + strMsg + ".txt";
            OutputTextLog(msgFilePath, "", m_MultiTransStartDate, m_MultiTransEndDate);
            lbtResultWordsAmount.Visible = (Directory.Exists(m_ResultDirPath_WordsAmount));
            MessageBox.Show("MultiTrans Finish!\r\n\r\n" + strMsg);
        }

        private void btnMultiTestByDiffWords_Click(object sender, EventArgs e)
        {
            m_ResultDirPath = m_ResultDirPath_MultiTrans_DiffWords + "\\" +
                              ddlThreadAmount.SelectedItem;
            if (Directory.Exists(m_ResultDirPath)) Directory.Delete(m_ResultDirPath, true);
            Directory.CreateDirectory(m_ResultDirPath);

            var scThreadContexts = new StringCollection();
            for (int i = 0; i < Convert.ToInt16(ddlThreadAmount.SelectedItem); i++)
            {
                string contextFilePath = AppDomain.CurrentDomain.BaseDirectory + "Diff_Words\\ForMultiTest\\words.txt";
                string strContext = GetTextFileContext(contextFilePath);
                strContext = strContext.Replace("\r\n", "").Replace("\r", "");
                string[] ss = strContext.Split(StringHelper.GetWordsSplitsKey());
                string sentence = GetSentence(strContext, ss, i*50, 50);
                if (!string.IsNullOrEmpty(sentence))
                    scThreadContexts.Add(sentence);
            }

            StartMultiThreads(scThreadContexts, FUNC_NAME_TRANS);

            int amount = 0;
            while (true)
            {
                Thread.Sleep(500);
                string[] fs = Directory.GetFiles(m_ResultDirPath);
                if (fs.Length == scThreadContexts.Count || amount > 10)
                    break;
                amount++;
            }

            CloseThreads();

            string strMsg = "Total Used Time_[" +
                            (m_MultiTransEndDate - m_MultiTransStartDate).TotalMilliseconds + "]ms";
            string msgFilePath = m_ResultDirPath + "\\" + strMsg + ".txt";
            OutputTextLog(msgFilePath, "", m_MultiTransStartDate, m_MultiTransEndDate);
            lbtResultMultiDiff.Visible = (Directory.Exists(m_ResultDirPath_MultiTrans_DiffWords));
            MessageBox.Show("MultiTrans Finish!\r\n\r\n" + strMsg);
        }

        private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            
        }

        private void TransTextByWebService_Load(object sender, EventArgs e)
        {
            ddlThreadAmount.SelectedIndex = 0;
            lstTargeLanguage.SelectedIndex = 5;
            lbtResultMultiSame.Visible = (Directory.Exists(m_ResultDirPath_MultiTrans_SameWords));
            lbtResultMultiDiff.Visible = (Directory.Exists(m_ResultDirPath_MultiTrans_DiffWords));
            lbtResultWordsAmount.Visible = (Directory.Exists(m_ResultDirPath_WordsAmount));
        }

        private void btnMultiTrans_Click(object sender, EventArgs e)
        {
            m_ResultDirPath = m_ResultDirPath_MultiTrans_SameWords + "\\" +
                              ddlThreadAmount.SelectedItem;
            if (Directory.Exists(m_ResultDirPath)) Directory.Delete(m_ResultDirPath, true);
            Directory.CreateDirectory(m_ResultDirPath);
            int threadAmount = Convert.ToInt32(ddlThreadAmount.SelectedItem);
            StartMultiThreads(threadAmount, FUNC_NAME_TRANS);

            int amount = 0;
            while (true)
            {
                Thread.Sleep(500);
                string[] fs = Directory.GetFiles(m_ResultDirPath);
                if (fs.Length == threadAmount || amount > 10)
                    break;
                amount++;
            }

            CloseThreads();
            lbtResultMultiSame.Visible = (Directory.Exists(m_ResultDirPath_MultiTrans_SameWords));
            MessageBox.Show("MultiTrans Finish!\r\n\r\nUsed Time : [" +
                            (m_MultiTransEndDate - m_MultiTransStartDate).TotalMilliseconds + "] ms");
        }

        private void lbtResultMultiSame_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            string dirPath = m_ResultDirPath_MultiTrans_SameWords;
            if (!Directory.Exists(dirPath))
                MessageBox.Show("testing result has not builded");
            else
                Process.Start("explorer.exe", dirPath);
        }

        private void lbtResultMultiDiff_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            string dirPath = m_ResultDirPath_MultiTrans_DiffWords;
            if (!Directory.Exists(dirPath))
                MessageBox.Show("testing result has not builded");
            else
                Process.Start("explorer.exe", dirPath);
        }

        private void lbtResultWordsAmount_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            string dirPath = m_ResultDirPath_WordsAmount;
            if (!Directory.Exists(dirPath))
                MessageBox.Show("testing result has not builded");
            else
                Process.Start("explorer.exe", dirPath);
        }
    }
}